<?php
// +----------------------------------------------------------------------
// | zhanshop-cloud / ProxyHttpclient.php    [ 2025/1/23 14:27 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2025 zhangqiquan All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhangqiquan <768617998@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace extend;

use zhanshop\App;
use zhanshop\client\Httpclient;
use zhanshop\Log;

class BridgeHttpclient extends Httpclient
{
    protected $account;
    protected $password;
    protected $proxy = [];
    public function __construct(string $account, string $password)
    {
        $this->account = $account;
        $this->password = $password;
    }
    /**
     * 设置代理
     * @param string $type 代理类型；支持http,socks5
     * @param string $name 代理池中的某个代理名称
     * @return void
     * @throws \Exception
     */
    public function setProxy(string $type = 'http', string $name = '')
    {
        $bridge = App::config()->get("bridge");
        $url = "http://".$bridge['ip'].':'.($bridge['port'] - 1).'/v1/bridge.pool';
        $httpClient = new Httpclient();
        $httpClient->setHeader('Authorization', 'Basic '.base64_encode($this->account.':'.$this->password));
        if($this->config['enable_ipv6']) $httpClient->enableIpv6();
        $result = $httpClient->request($url);
        if($result['code'] != 200){
            App::error()->setError("桥接服务错误".$result['code']);
        }
        $body = json_decode($result['body'], true);
        $data = $body['data'] ?? [];
        if($data == false){
            App::error()->setError("无可用的桥接设备", 417);
        }
        if($name == false){
            $bridgeClient =  $data[rand(0, count($data) - 1)] ?? [];
        }else{
            $bridgeClient = [];
            foreach ($data as $k => $v){
                if($v['name'] == $name){
                    $bridgeClient = $v;
                    break;
                }
            }
            if($bridgeClient == false) App::error()->setError($name.'代理不在线', 417);
        }

        $proxy = $bridgeClient['proxy'] ?? [];
        if($proxy == false) App::error()->setError("桥接连接参数返回格式错误");
        $this->proxy = $bridgeClient;
        if($type == 'http'){
            $this->httpproxy($bridge['ip'], $proxy['http_port'], $proxy['user'], $proxy['pwd']);
        }else{
            $this->socks5($bridge['ip'], $proxy['socks5_port'], $proxy['user'], $proxy['pwd']);
        }
    }

    /**
     * 请求
     * @param string $url
     * @param string $method
     * @param string|array $data
     * @param bool $again
     * @return void
     */
    public function request(string $url, string $method = 'GET', string|array $data = [], bool $again = false)
    {
        $debug = $this->config['debug'];
        $this->config['debug'] = false;
        $result = parent::request($url, $method, $data, $again);
        $result['proxy'] = $this->proxy;
        if($debug) $this->debugLog($url, $method, $data, $result);
        return $result;
    }

    private function debugLog($url,  $method, $param, $output)
    {
        if(is_string($output["body"]) && strlen($output["body"]) > 2000){
            $output["body"] = substr($output["body"], 0, 2000);
        }
        App::log()->push(json_encode([
            'url' => $url,
            'method' => $method,
            'header' => $this->config['header'],
            'param' => $param,
            'result' => $output
        ]), Log::NOTICE, 'BRIDGE_CLIENT');
    }
}